<template>
  <table-page
    ref="tablePageRef"
    title="分类列表"
    :search-config="searchConfig"
    :columns="tableConfig"
    :data="processedTableData"
    :loading="loading"
    :pagination-config="paginationConfig"
    :form-config="formConfig"
    :default-form-data="getDefaultFormData()"
    @search="handleSearch"
    @reset="handleReset"
    @selection-change="handleSelectionChange"
    @size-change="handleSizeChange"
    @current-change="handleCurrentChange"
    @add="handleAdd"
    @edit="handleEdit"
    @delete="handleDelete"
    @batch-delete="handleBatchDelete"
  />
</template>

<script setup>
/**
 * 文章分类管理页面
 *
 * 功能：
 * 1. 分类列表展示与搜索
 * 2. 分类的添加、编辑、删除和批量删除
 * 3. 分类排序管理
 * 4. 列表分页与数据加载
 */
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import TablePage from '@/components/TablePage/index.vue'
import { searchConfig, tableConfig } from './config/pageConfig'
import { formConfig, getDefaultFormData } from './config/formConfig'
import { categoryApi } from '@/api/category'

// =============== 状态与配置 ===============

/**
 * 组件引用与状态
 */
const tablePageRef = ref(null)
const loading = ref(false)
const tableData = ref([])
const searchParams = ref({})

/**
 * 分页数据
 * 控制列表分页
 */
const pagination = reactive({
  currentPage: 1, // 当前页码
  pageSize: 10, // 每页条数
  total: 0, // 总条数
})

/**
 * 分页配置
 * 传递给表格组件的分页参数
 */
const paginationConfig = computed(() => ({
  total: pagination.total,
  currentPage: pagination.currentPage,
  pageSize: pagination.pageSize,
  pageSizes: [10, 20, 30, 50],
}))

// =============== 方法 ===============

/**
 * 获取分类列表
 * 根据搜索参数和分页配置加载数据
 */
const fetchCategoryList = async () => {
  try {
    loading.value = true
    const params = {
      ...searchParams.value,
      pageNum: pagination.currentPage,
      pageSize: pagination.pageSize,
    }
    const res = await categoryApi.getList(params)
    tableData.value = res.records
    pagination.total = res.total
  } catch (error) {
    console.error('获取分类列表失败:', error)
    ElMessage.error('获取分类列表失败')
  } finally {
    loading.value = false
  }
}

/**
 * 搜索处理
 * 更新搜索参数并重新加载数据
 * @param {Object} params - 搜索参数
 */
const handleSearch = (params) => {
  searchParams.value = params
  pagination.currentPage = 1
  fetchCategoryList()
}

/**
 * 重置处理
 * 清空搜索参数并重新加载数据
 */
const handleReset = () => {
  searchParams.value = {}
  pagination.currentPage = 1
  fetchCategoryList()
}

/**
 * 选择行变化
 * @param {Array} rows - 选中的行数据
 */
const handleSelectionChange = (rows) => {
  console.log('选中行：', rows)
}

/**
 * 每页条数变化
 * @param {number} val - 新的每页条数
 */
const handleSizeChange = (val) => {
  pagination.pageSize = val
  fetchCategoryList()
}

/**
 * 页码变化
 * @param {number} val - 新的页码
 */
const handleCurrentChange = (val) => {
  pagination.currentPage = val
  fetchCategoryList()
}

/**
 * 新增分类
 * @param {Object} data - 新分类数据
 */
const handleAdd = async (data) => {
  try {
    loading.value = true
    await categoryApi.addCategory(data)
    ElMessage.success('新增成功')
    fetchCategoryList()
  } catch (error) {
    console.error('新增分类失败:', error)
    ElMessage.error('新增分类失败')
  } finally {
    loading.value = false
  }
}

/**
 * 编辑分类
 * @param {Object} data - 更新后的分类数据
 */
const handleEdit = async (data) => {
  try {
    loading.value = true
    await categoryApi.updateCategory(data)
    ElMessage.success('保存成功')
    fetchCategoryList()
  } catch (error) {
    console.error('编辑分类失败:', error)
    ElMessage.error('编辑分类失败')
  } finally {
    loading.value = false
  }
}

/**
 * 删除分类
 * 删除单个分类
 * @param {Object} row - 要删除的分类
 */
const handleDelete = async (row) => {
  try {
    loading.value = true
    await categoryApi.deleteCategory([row.id])
    ElMessage.success('删除成功')
    fetchCategoryList()
  } finally {
    loading.value = false
  }
}

/**
 * 批量删除
 * 删除多个选中的分类
 * @param {Array} rows - 要删除的分类数组
 */
const handleBatchDelete = async (rows) => {
  try {
    loading.value = true
    const ids = rows.map((row) => row.id)
    await categoryApi.deleteCategory(ids)
    ElMessage.success('删除成功')
    fetchCategoryList()
    tablePageRef.value?.clearSelection()
  } finally {
    loading.value = false
  }
}

/**
 * 处理上移
 * 调整分类排序顺序
 * @param {Object} row - 要调整的分类
 */
const handleMoveUp = async (row) => {
  const index = tableData.value.findIndex((item) => item.id === row.id)
  if (index <= 0) return

  try {
    loading.value = true
    const newData = JSON.parse(JSON.stringify(tableData.value))

    const currentOrder = newData[index].orderNum
    const targetOrder = newData[index - 1].orderNum

    // 如果当前序号已经是0，则不允许上移
    if (currentOrder === 0) return

    if (currentOrder === targetOrder) {
      // 序号相同时，减小当前序号，但不能小于0
      const newOrder = Math.max(currentOrder - 1, 0)
      await categoryApi.updateOrder(newData[index].id, newOrder)
    } else {
      // 序号不同时，交换序号
      await categoryApi.updateOrder(newData[index].id, targetOrder)
      await categoryApi.updateOrder(newData[index - 1].id, currentOrder)
    }

    // 刷新列表
    await fetchCategoryList()
    ElMessage.success('移动成功')
  } catch (error) {
    console.error('移动失败:', error)
    ElMessage.error('移动失败')
  } finally {
    loading.value = false
  }
}

/**
 * 处理下移
 * 调整分类排序顺序
 * @param {Object} row - 要调整的分类
 */
const handleMoveDown = async (row) => {
  const index = tableData.value.findIndex((item) => item.id === row.id)
  if (index >= tableData.value.length - 1) return

  try {
    loading.value = true
    const newData = JSON.parse(JSON.stringify(tableData.value))

    const currentOrder = newData[index].orderNum
    const targetOrder = newData[index + 1].orderNum

    if (currentOrder === targetOrder) {
      // 序号相同时，增加当前序号
      await categoryApi.updateOrder(newData[index].id, currentOrder + 1)
    } else {
      // 序号不同时，交换序号
      await categoryApi.updateOrder(newData[index].id, targetOrder)
      await categoryApi.updateOrder(newData[index + 1].id, currentOrder)
    }

    // 刷新列表
    await fetchCategoryList()
    ElMessage.success('移动成功')
  } catch (error) {
    console.error('移动失败:', error)
    ElMessage.error('移动失败')
  } finally {
    loading.value = false
  }
}

// =============== 计算属性 ===============

/**
 * 处理后的表格数据
 * 为每一行添加排序方法和按钮状态
 */
const processedTableData = computed(() => {
  return tableData.value.map((item) => ({
    ...item,
    onMoveUp: handleMoveUp,
    onMoveDown: handleMoveDown,
    upDisabled: item.orderNum === 0, // 添加上移按钮禁用状态
  }))
})

// =============== 生命周期 ===============

/**
 * 页面加载时获取数据
 */
onMounted(() => {
  fetchCategoryList()
})
</script>

<style lang="scss" scoped>
// 导入主题变量和混合器
@use '@/assets/styles/theme/base.scss' as *;
@use '@/assets/styles/mixins.scss' as *;

/**
 * 分类管理页面样式
 */
.category {
  /**
   * 数字输入框样式
   */
  :deep(.number-input) {
    width: 100%;

    // 隐藏上下调节按钮
    &::-webkit-inner-spin-button,
    &::-webkit-outer-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }

    /* Firefox */
    -moz-appearance: textfield;
  }
}

/**
 * 按钮悬浮效果
 */
:deep(.el-button) {
  &:hover {
    .el-icon {
      transform: scale(1.2);
    }
  }

  .el-icon {
    @include transition(transform);
  }
}
</style>
